package cn.com.wxd.service.permissions.core;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.com.wxd.service.permissions.entity.FunctionPermissions;
import cn.com.wxd.service.permissions.entity.ModelPermissions;
import cn.com.wxd.service.permissions.entity.PermissionsEntity;
import cn.com.wxd.service.permissions.entity.RoleEntity;

/**
 * Title:角色处理核心类
 * Description:对配置在xml中的数据进行复杂的处理和验证
 * <p>
 * Company: Amumu管理平台
 * Copyright: Copyright (c) 2016
 * All right reserved.
 * Created time: 2017-1-5 下午3:12:08
 *
 * @author WangXuDong
 * @version 2.0
 */
public class RoleCore {
    private static final String FILENAMEPATH = "user-role.xml";
    private static final Logger log = LoggerFactory.getLogger(RoleCore.class);
    private static List<RoleEntity> roles = null;
    private static RoleCore roleCore;

    private RoleCore() throws Exception {
        init();
        if (!checkData()) {
            throw new Exception("角色配置文件生成数据校验错误!");
        }
    }

    public static RoleCore getInstance() throws Exception {
        if (roleCore == null) {
            roleCore = new RoleCore();
        }
        return roleCore;
    }

    private void init() throws Exception {
        Document document;
        try {
            SAXReader reader = new SAXReader();
            reader.setEncoding("UTF-8");
            InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(FILENAMEPATH);
            document = reader.read(inputStream);
        } catch (DocumentException e) {
            log.error("读取xml文件路径配置文件错误！", e);
            throw e;
        }
        //开始解析
        roles = new ArrayList<>();
        Element root = document.getRootElement();
        List nodes = root.elements("role");  //解析系统所有权限
        for (int i = 0; i < nodes.size(); i++) {
            Element roleEle = (Element) nodes.get(i);
            List sysPerms = roleEle.elements("system-permiss");
            List<PermissionsEntity> rolepermises = new ArrayList<PermissionsEntity>();
            for (int j = 0; j < sysPerms.size(); j++) {
                Element sysPerm = (Element) sysPerms.get(j);
                List modelEles = sysPerm.elements("model-permiss");
                List<ModelPermissions> modelPerms = new ArrayList<ModelPermissions>();
                for (int k = 0; k < modelEles.size(); k++) {
                    Element modelPerm = (Element) modelEles.get(k);
                    String stesvalue = getAttributeByElement(modelPerm, "function-permiss");
                    List<FunctionPermissions> funPerms = new ArrayList<FunctionPermissions>();
                    //加载操作权限
                    if (stesvalue != null && !stesvalue.trim().equals("")) {
                        String[] stes = stesvalue.split(",");
                        if (stes != null) {
                            for (int m = 0; m < stes.length; m++) {
                                FunctionPermissions funp = new FunctionPermissions();
                                funp.setCode(stes[m]);
                                funPerms.add(funp);
                            }
                        }
                    }
                    //这里加模块权限
                    ModelPermissions modelPer = new ModelPermissions();
                    modelPer.setCode(getAttributeByElement(modelPerm, "code"));
                    modelPer.setFunctionPermissions(funPerms);
                    if (modelPer.getCode() != null && !modelPer.getCode().trim().equals("")) {
                        modelPerms.add(modelPer);
                    }
                }
                //加载系统权限
                PermissionsEntity permEntity = new PermissionsEntity();
                permEntity.setCode(getAttributeByElement(sysPerm, "code"));
                permEntity.setModelPermissions(modelPerms);
                if (permEntity.getCode() != null && !permEntity.getCode().trim().equals("")) {
                    rolepermises.add(permEntity);
                }
            }
            /**
             * 加载角色权限
             */
            RoleEntity role = new RoleEntity();
            role.setGroup(getAttributeByElement(roleEle, "group"));
            role.setName(getAttributeByElement(roleEle, "name"));
            role.setCode(getAttributeByElement(roleEle, "rolecode"));
            role.setDesctipt(getAttributeByElement(roleEle, "desctipt"));
            role.setPermises(rolepermises);
            if (role.getCode() != null && !role.getCode().trim().equals("")) {
                roles.add(role);
            }
        }

    }

    /**
     * 根据Element的属性名或子节点名称获取属性值，
     * 如果该属性或节点不存在则返回空字符串
     * 如果同时配置，属性优先级大于节点
     *
     * @return
     */
    private String getAttributeByElement(Element element, String arrtibuteName) {
        String value = "";
        if (element == null) {
            value = "";
        }
        List attrList = element.attributes();
        for (int i = 0; i < attrList.size(); i++) {
            //属性的取得
            Attribute item = (Attribute) attrList.get(i);
            if (item != null && item.getName().equalsIgnoreCase(arrtibuteName)) {
                value = item.getValue();
                return value;
            }
        }
        if (value == null || value.trim().equalsIgnoreCase("")) {
            Element ele = element.element(arrtibuteName);
            if (ele != null) {
                value = ele.getTextTrim();
                if (value == null) {
                    value = "";
                }
            }
        }
        return value;
    }

    /**
     * TODO 检查数据的正确性，即检查重复性和空配置
     */
    private boolean checkData() {
        return true;
    }

    public List<RoleEntity> getRoles() {
        return roles;
    }

    public RoleEntity getRoles(String code) {
        if (roles != null) {
            for (RoleEntity role : roles) {
                if (role.getCode().equalsIgnoreCase(code)) {
                    return role;
                }
            }
        }
        return null;
    }
}
